﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.IO;
using System.Data;
using System.Data.SqlClient;
using System.Xml.Serialization;

namespace ScriptIT
{
    [Serializable(),XmlInclude(typeof(Column))]
    public class Columns:IEnumerable
    {
        private List<Column> m_colColumns = new List<Column>();
        Database _database;
        string _TableName;
        public Columns(Database database, string sTableName)
        {
            _database = database;
            _TableName = sTableName;
            this.Refresh();
        }

        public Columns() { }
        public static Columns operator +(Columns cols1, Columns cols2)
        {
            cols2._database = cols1._database;
            return cols2;
        }
        public void Add(object column)
        {
            m_colColumns.Add((Column)column);
        }

        [XmlArrayItem(typeof(Column))]
        public List<Column> AsList
        {
            get
            {
                return m_colColumns;
            }
        }

        [XmlArrayItem(typeof(Column))]
        public List<Column> GetSelectColumns
        {
            get
            {
                List<Column> _Columns = new List<Column>();
                foreach (Column oCols in m_colColumns)
                {
                    if (oCols.Include)
                        _Columns.Add(oCols);
                }
                return _Columns;
            }
        }
        
        public delegate void CurrentStatusHandler(string message);
        public event CurrentStatusHandler CurrentStatus;

        public delegate void CurrentProgressHandler(double Progress);
        public event CurrentProgressHandler CurrentProgress;
       
         private class ColumnEnumerator : IEnumerator
        {
            #region local vars

            private int m_iPos = -1;
            private Columns objDataColumns;

            #endregion

            #region constructors

            public ColumnEnumerator(Columns objDataEntries)
            {
                this.objDataColumns = objDataEntries;
            }

            #endregion

            #region attrributes

            public object Current
            {
                get
                {
                    return
                        objDataColumns.m_colColumns[m_iPos];
                }
            }

            #endregion

            #region public operations

            public bool MoveNext()
            {
                if (m_iPos < objDataColumns.m_colColumns.Count - 1)
                {
                    m_iPos++;
                    return true;
                }
                else
                    return false;
            }

            public void Reset()
            {
                m_iPos = -1;
            }

            #endregion

        }
         private void RaiseCurrentStatus(string message)
         {
             if (CurrentStatus != null)
                 CurrentStatus(message);
         }

         private void RaiseCurrentProgress(double dCurrentPercent)
         {
             if (CurrentProgress != null)
                 CurrentProgress(dCurrentPercent);
         }
        #region Public Methods

        public IEnumerator GetEnumerator()
        {
            return new ColumnEnumerator(this);
        }

        public List<Column> Refresh()
        {
            DataTable dt = null;

            try
            {
                if (_database == null)
                    return m_colColumns;

                SqlParameter[] sqlParms = new SqlParameter[] 
                { 
                    new SqlParameter("@table_name", _TableName), 
                    new SqlParameter("@table_owner", "%"),
                    new SqlParameter("@table_qualifier", _database.Connection.Database),
                    new SqlParameter("@column_name", "%"),
                    new SqlParameter("@ODBCVer", 2) 
                };
                DataSet dset = _database.ExecuteSP( "sp_columns", sqlParms);

                if ((dset != null) && (dset.Tables.Count > 0))
                    dt = dset.Tables[0];
            }
            catch (Exception ex)
            {
                throw new Exception("GetDatabaseTableColumns error: " + ex.Message);
            }

            foreach (DataRow oDR in dt.Rows)
            {
                Column oCol = new Column(oDR);
                m_colColumns.Add(oCol);
            }
            return m_colColumns;
        }

        public int Count()
        {
            return m_colColumns.Count;
        }
        #endregion

    }

    [Serializable()]
    public class Column
    {
        bool _Include = true;
        string _Name = string.Empty;
        string _ChangedName = string.Empty;
        string _DefaultValue = string.Empty;
        bool _OverRide = false;
        string _DataTypeName = string.Empty;

        int _Length = 0;
        bool _AllowNull = false;

        public Column(DataRow oDR)
        {
            _Name = oDR["COLUMN_NAME"].ToString();
            _ChangedName = _Name;
            _DataTypeName = oDR["TYPE_NAME"].ToString();
            _Length = (int)oDR["LENGTH"];
            _AllowNull = Convert.ToBoolean( oDR["NULLABLE"]);
        }
        public Column() { }
        #region Attributes

        [System.Xml.Serialization.XmlElementAttribute("Include")]
        public bool Include
        {
            get { return _Include; }
            set { _Include = value; }
        }

        [System.Xml.Serialization.XmlElementAttribute("Name")]
        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }

        [System.Xml.Serialization.XmlElementAttribute("ChangedName")]
        public string ChangedName
        {
            get { return _ChangedName; }
            set { _ChangedName = value; }
        }

        [System.Xml.Serialization.XmlElementAttribute("DefaultValue")]
        public string DefaultValue
        {
            get { return _DefaultValue; }
            set 
            { 
                _DefaultValue = value;
                //_OverRide = (_DefaultValue.Length != 0);
            }
        }

        [System.Xml.Serialization.XmlElementAttribute("OverRide")]
        public bool OverRide
        {
            get { return _OverRide; }
            set 
            { 
                _OverRide = value;
                //if (!_OverRide)
                //    _DefaultValue = string.Empty;
            }
        }

        [System.Xml.Serialization.XmlElementAttribute("DataTypeName")]
        public string DataTypeName
        {
            get { return _DataTypeName; }
            set { _DataTypeName = value; }
        }
        
        public override string ToString()
        {
            return _Name;
        }

        #endregion

        public string GetScript()
        {
            return string.Empty;
        }
    }
}
